#pragma once


#include <YSimpleSystem/YSimpleSystem.h>
#include <YSimpleSystem/ISystemFactory.h>
#include <YSimpleSystem/IProactor.h>
#include <YSimpleSystem/IStream.h>

#include <YSimpleNetwork/YSimpleNetwork.h>
#include <YSimpleNetwork/ITcpSession.h>
#include <YSimpleNetwork/INetworkFactory.h>
#include <YSimpleNetwork/ITcpSessionCallback.h>
#include <YSimpleNetwork/YEndPoint.h>
#include <YSimpleNetwork/YMessageBlock.h>
#include <YSimpleNetwork/IUDPSession.h>
#include <YSimpleNetwork/IUDPSessionCallback.h>
using namespace ysimple_network;


#include <iostream>
#include <windows.h>
#include <ostream>

namespace yconsole
{
	enum Color
	{
		black = 0,
		blue = 1,
		green = 2,
		cyan = blue+green,
		red = 4,
		magenta = blue + red, 
		brown = green + red,
		lightgray = blue + green + red, 
		darkgray = 8,
		intensity = 8,
		lightblue = blue + intensity,
		lightgreen = green + intensity, 
		lightcyan = blue + green + intensity ,
		lightred = red + intensity, 
		lightmagenta = blue + red + intensity ,
		yellow = green + red + intensity ,
		white = blue + green + red + intensity ,

	};
	class ConsoleTextColor
	{

	private:
		HANDLE  m_stdout;
		CONSOLE_SCREEN_BUFFER_INFO              m_csbi;
		Color           m_fg;
		Color           m_bg;
	public:
		ConsoleTextColor() 
			: m_stdout(GetStdHandle( STD_OUTPUT_HANDLE ))           
		{
			GetConsoleScreenBufferInfo(m_stdout , &m_csbi );
		}

		~ConsoleTextColor()
		{
			SetConsoleTextAttribute( m_stdout, m_csbi.wAttributes );
		}

		void fg_color(Color color) 
		{
			m_fg = color;
			SetConsoleTextAttribute( m_stdout, (m_bg << 4) | color );
		}

		void bg_color(Color color) 
		{
			m_bg = color;
			SetConsoleTextAttribute( m_stdout, (color << 4) | m_fg );
		}

		static ConsoleTextColor&        getInstance()
		{
			static ConsoleTextColor _ins;
			return _ins;
		}

	};

#define DEC_OSTREAM_COLOR(color)        \
	inline std::ostream& fg_##color( std::ostream& os )     \
	{\
	ConsoleTextColor::getInstance().fg_color(color);\
	return os;\
	}\
	inline std::ostream& bg_##color( std::ostream& os )     \
	{\
	ConsoleTextColor::getInstance().bg_color(color);\
	return os;\
	}\
	inline std::wostream& fg_##color( std::wostream& os )   \
	{\
	ConsoleTextColor::getInstance().fg_color(color);\
	return os;\
	}\
	inline std::wostream& bg_##color( std::wostream& os )   \
	{\
	ConsoleTextColor::getInstance().bg_color(color);\
	return os;\
	}

	DEC_OSTREAM_COLOR(red)
		DEC_OSTREAM_COLOR(green)
		DEC_OSTREAM_COLOR(blue)
		DEC_OSTREAM_COLOR(white)
		DEC_OSTREAM_COLOR(cyan)
		DEC_OSTREAM_COLOR(magenta)
		DEC_OSTREAM_COLOR(yellow)
		DEC_OSTREAM_COLOR(black)
		DEC_OSTREAM_COLOR(brown)
		DEC_OSTREAM_COLOR(lightgray)
		DEC_OSTREAM_COLOR(darkgray)
		DEC_OSTREAM_COLOR(intensity)
		DEC_OSTREAM_COLOR(lightblue)
		DEC_OSTREAM_COLOR(lightgreen)
		DEC_OSTREAM_COLOR(lightcyan)
		DEC_OSTREAM_COLOR(lightred)
		DEC_OSTREAM_COLOR(lightmagenta)
}
